package com.app.service.impl;

import com.app.domain.bo.FilesBo;
import com.app.domain.page.Page;
import com.app.domain.po.FilesPo;
import com.app.domain.vo.FilesVo;
import com.app.domain.vo.user.UserVo;
import com.app.framework.config.UploadConfig;
import com.app.framework.utils.CollectionUtils;
import com.app.framework.utils.FileUtils;
import com.app.framework.utils.TokenUtils;
import com.app.mapper.FilesMapper;
import com.app.service.FilesService;
import com.app.service.user.UserCommonService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 文件管理方法实现
 */
@Service
public class FilesServiceImpl extends ServiceImpl<FilesMapper, FilesPo> implements FilesService {

    @Resource
    private UploadConfig uploadConfig;

    @Resource
    private UserCommonService userCommonService;

    /**
     * 文件列表
     *
     * @param bo 入参
     */
    @Override
    @Cacheable(cacheNames = "file", key = "#bo.getPageNum")
    public Page<FilesVo> lists(FilesBo bo) {
        PageHelper.startPage(bo.getPageNum(), bo.getPageSize());
        List<FilesVo> filesVos = baseMapper.lists(bo);
        if (CollectionUtils.isEmpty(filesVos)) {
            return Page.restPage(new ArrayList<>());
        }
        List<Long> userIds = new ArrayList<>();
        for (FilesVo filesVo : filesVos) {
            userIds.add(filesVo.getUserId());
        }
        Map<Long, UserVo> userMap = userCommonService.getUserMap(userIds);
        for (FilesVo filesVo : filesVos) {
            filesVo.setUser(userMap.get(filesVo.getUserId()));
        }
        return Page.restPage(filesVos);
    }

    /**
     * 上传文件
     *
     * @param file 文件
     * @param path 路径
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "file", allEntries = true)
    public String uploadOne(MultipartFile file, String path) throws IOException {
        Long loginUserId = TokenUtils.getLoginUserId();
        //获取文件MD5值
        String md5 = FileUtils.getMd5(file);
        //获取文件后缀名
        String suffix = FileUtils.getFileExtension(file);
        //查询文件是否已上传过
        FilesVo filesVo = baseMapper.selectFileByMd5(md5);
        if (filesVo != null) {
            return filesVo.getUrl();
        } else {
            //上传路径
            String fileRoot = uploadConfig.getFileRoot() + "/" + path;
            //开始上传
            String update = FileUtils.fileUpload(file, path, fileRoot);
            //上传成功后链接
            String url = uploadConfig.getDomain() + update;
            //保存文件信息
            FilesPo filesPo = new FilesPo();
            filesPo.setUrl(url);
            filesPo.setMd5(md5);
            filesPo.setFileType("." + suffix);
            filesPo.setUserId(loginUserId);
            filesPo.setCreateTime(new Date());
            baseMapper.insert(filesPo);
            return url;
        }
    }

    /**
     * 删除文件
     *
     * @param fileId 文件ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "file", allEntries = true)
    public void deleteOne(Long fileId) {
        //查询文件信息
        FilesPo filesPo = baseMapper.selectById(fileId);
        if (CollectionUtils.isNoNull(filesPo)) {
            String url = filesPo.getUrl();
            //删除文件
            String filePath = url.replace(uploadConfig.getDomain() + "/file/", uploadConfig.getFileRoot() + "/");
            FileUtils.deleteFile(filePath);
            //删除数据库记录
            baseMapper.deleteById(fileId);
        }
    }

}